package dao

import (
	"car_rental/shared/id"
	mgutil "car_rental/shared/mongo"
	"car_rental/shared/mongo/objid"
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

const openIdField = "open_id"

// Mongo MongoDao
type Mongo struct {
	col *mongo.Collection
}

// NewMongo 创建一个MongoDao
func NewMongo(db *mongo.Database) *Mongo {
	return &Mongo{
		col: db.Collection("account"),
	}
}

// ResolveAccountId 处理用户ID
func (m *Mongo) ResolveAccountId(c context.Context, openId string) (id.AccountId, error) {

	insertedId := mgutil.NewObjId()

	res := m.col.FindOneAndUpdate(c,
		bson.M{openIdField: openId},
		mgutil.SetOneInsert(bson.M{
			mgutil.IdFieldName: insertedId,
			openIdField:        openId,
		}),
		options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.After),
	)

	if err := res.Err(); err != nil {
		return "", fmt.Errorf("cannot FindOneAndUpdate: %v", err)
	}

	var row mgutil.IdField
	err := res.Decode(&row)

	if err != nil {
		return "", fmt.Errorf("cannot Decode res: %v", err)
	}

	return objid.ToAccountId(row.Id), nil

}
